﻿using System.Net;
#if NET461
using System.Net.Http;
#endif

namespace OkFlurl
{
    internal class FlurlProgressStream : HttpContent
    {
        private readonly Stream _inputStream;
        private readonly FlurlForm _form;
        private readonly string _fileName;
        private readonly long? _length;

        public FlurlProgressStream()
        {
        }

        public FlurlProgressStream(Stream stream, FlurlForm form, string fileName, long? length)
        {
            _inputStream = stream;
            _form = form;
            _fileName = fileName;
            _length = length;
        }

        protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context)
        {
            if (_form.UploadProgress == null || !_length.HasValue)
            {
                await _inputStream.CopyToAsync(stream, _form.UploadBufferSize, _form.Token);
            }
            else
            {
                _form.UploadProgress.FileName = _fileName;
                int currentRead;
                var buffer = new byte[_form.UploadBufferSize];
                do
                {
                    _form.Token.ThrowIfCancellationRequested();

                    if (_form.UploadProgress.IsStop)
                    {
                        await _form.UploadProgress.WaitAsync();
                    }

#if NET461 || NETSTANDARD2_0
                    currentRead = await _inputStream.ReadAsync(buffer, 0, buffer.Length, _form.Token);
#else
                    currentRead = await _inputStream.ReadAsync(buffer, _form.Token);
#endif
                    if (currentRead > 0)
                    {
                        _form.UploadCurrSize += currentRead;

#if NET461 || NETSTANDARD2_0
                        await stream.WriteAsync(buffer, 0, currentRead, _form.Token).ConfigureAwait(false);
#else
                        await stream.WriteAsync(buffer.AsMemory(0, currentRead), _form.Token);
#endif
                        await stream.FlushAsync(_form.Token); //及时释放，把数据传递到服务器

                        _form.ChangeUploadSize();
                    }

                } while (currentRead > 0);
            }
        }

        protected override bool TryComputeLength(out long length)
        {
            length = -1;
            return false;
        }
    }
}
